"""
智能模型选择器
根据任务需求自动选择最佳的AI模型

支持的任务类型包括：
1. chat - 聊天对话任务
2. code - 代码生成任务
3. image - 图像识别任务
4. speech - 语音识别任务
5. video - 视频分析任务
6. time_series - 时间序列预测任务
7. recommendation - 推荐系统任务
8. anomaly - 异常检测任务
"""

import time
import logging
from typing import Dict, Any, Optional
from src.research_core.model_manager import ModelManager, ModelType
from src.research_core.model_evaluator import ModelEvaluator


# 配置日志
logger = logging.getLogger(__name__)


class IntelligentModelSelector:
    """智能模型选择器"""
    
    def __init__(self):
        """初始化智能模型选择器"""
        try:
            self.model_manager = ModelManager()
            self.model_evaluator = ModelEvaluator()
            self.task_history: Dict[str, str] = {}  # 任务类型到最佳模型的映射
            self.selection_count: Dict[str, int] = {}  # 模型选择计数
            self.total_selection_time: float = 0.0  # 总选择时间
            self.selection_calls: int = 0  # 选择调用次数
        except Exception as e:
            logger.error(f"初始化智能模型选择器失败: {e}")
            raise
    
    def select_model_for_task(self, task_type: str, task_description: str, 
                            requirements: Optional[Dict[str, Any]] = None):
        """为特定任务选择最佳模型
        
        Args:
            task_type: 任务类型
            task_description: 任务描述
            requirements: 任务需求参数
            
        Returns:
            最适合该任务的模型实例
        """
        start_time = time.time()
        try:
            if requirements is None:
                requirements = {
                    "time_weight": 0.4,
                    "accuracy_weight": 0.5,
                    "error_weight": 0.1
                }
            
            # 首先检查是否有历史记录
            if task_type in self.task_history:
                model_name = self.task_history[task_type]
                model = self._get_model_by_name(model_name)
                if model:
                    self._record_selection_metrics(start_time, model_name)
                    logger.debug(f"使用历史记录选择模型: {model_name} for task {task_type}")
                    return model
            
            # 根据需求选择最佳模型
            best_model_name = self.model_evaluator.select_best_model(task_type, requirements)
            if best_model_name:
                self.task_history[task_type] = best_model_name
                self._record_selection_metrics(start_time, best_model_name)
                model = self._get_model_by_name(best_model_name)
                if model:
                    logger.debug(f"基于评估选择模型: {best_model_name} for task {task_type}")
                    return model
            
            # 根据任务类型选择默认模型
            default_model = self._select_default_model_by_task_type(task_type)
            if default_model:
                self._record_selection_metrics(start_time, default_model.__class__.__name__)
                logger.debug(f"使用任务类型默认模型: {task_type}")
                return default_model
            
            # 默认返回聊天模型
            model = self.model_manager.get_model(ModelType.CHAT)
            self._record_selection_metrics(start_time, model.__class__.__name__ if model else "Unknown")
            logger.debug("使用默认聊天模型")
            return model
        except Exception as e:
            logger.error(f"模型选择过程出错: {e}")
            # 出错时返回默认聊天模型
            model = self.model_manager.get_model(ModelType.CHAT)
            self._record_selection_metrics(start_time, model.__class__.__name__ if model else "Unknown")
            return model
    
    def _select_default_model_by_task_type(self, task_type: str):
        """根据任务类型选择默认模型
        
        Args:
            task_type: 任务类型
            
        Returns:
            对应的默认模型实例
        """
        task_type_to_model_map = {
            "chat": ModelType.CHAT,
            "code": ModelType.CODE_GENERATION,
            "image": ModelType.IMAGE_RECOGNITION,
            "speech": ModelType.SPEECH_RECOGNITION,
            "video": ModelType.VIDEO_ANALYSIS,
            "time_series": ModelType.TIME_SERIES_FORECASTING,
            "recommendation": ModelType.RECOMMENDATION_SYSTEM,
            "anomaly": ModelType.ANOMALY_DETECTION
        }
        
        # 根据任务类型关键词匹配
        for keyword, model_type in task_type_to_model_map.items():
            if keyword in task_type.lower():
                return self.model_manager.get_model(model_type)
        
        return None
    
    def _get_model_by_name(self, model_name: str):
        """根据模型名称获取模型实例
        
        Args:
            model_name: 模型名称
            
        Returns:
            对应的模型实例，如果找不到则返回None
        """
        try:
            # 查找匹配的模型
            for model_type, model in self.model_manager.models.items():
                if model and model.__class__.__name__ == model_name:
                    return model
            return None
        except Exception as e:
            logger.error(f"根据名称获取模型失败: {e}")
            return None
    
    def _record_selection_metrics(self, start_time: float, model_name: str):
        """记录选择指标
        
        Args:
            start_time: 选择开始时间
            model_name: 选择的模型名称
        """
        try:
            # 记录选择时间
            selection_time = time.time() - start_time
            self.total_selection_time += selection_time
            self.selection_calls += 1
            
            # 记录模型选择计数
            if model_name in self.selection_count:
                self.selection_count[model_name] += 1
            else:
                self.selection_count[model_name] = 1
        except Exception as e:
            logger.error(f"记录选择指标失败: {e}")
    
    def optimize_model_selection(self, task_type: str, actual_performance: Dict[str, Any]):
        """根据实际性能优化模型选择
        
        Args:
            task_type: 任务类型
            actual_performance: 实际性能数据
        """
        try:
            # 更新性能数据
            # 在实际实现中，这里会根据实际性能数据更新模型评估器中的性能记录
            # 重新评估模型选择策略
            pass
        except Exception as e:
            logger.error(f"优化模型选择失败: {e}")
    
    def get_selection_metrics(self) -> Dict[str, Any]:
        """获取选择指标
        
        Returns:
            包含选择指标的字典
        """
        try:
            return {
                "total_selection_calls": self.selection_calls,
                "average_selection_time": self.total_selection_time / max(self.selection_calls, 1),
                "model_selection_count": self.selection_count,
                "task_history": self.task_history
            }
        except Exception as e:
            logger.error(f"获取选择指标失败: {e}")
            return {}
    
    def get_model_performance_report(self) -> Dict[str, Dict[str, float]]:
        """获取模型性能报告
        
        Returns:
            模型性能报告
        """
        try:
            return self.model_evaluator.get_model_performance_report()
        except Exception as e:
            logger.error(f"获取模型性能报告失败: {e}")
            return {}